#include "stdafx.h"

#pragma once

int Strcmp(const char * src, const char * dst)
{
	int ret = 0;

	while(!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
	{
		++src, ++dst;
	}

	return (ret > 0) - (ret < 0);
}

int Stricmp(const char * src, const char * dst)
{
	int ret = 0;

	while(!(ret = tolower(*(unsigned char *)src) - tolower(*(unsigned char *)dst)) && *dst)
	{
		++src, ++dst;
	}

	return (ret > 0) - (ret < 0);
}

size_t Strlen(const char * src)
{
	const char * eos = src;
	while(*eos++);
	return (eos - src - 1);
}

size_t Strlen(const char * src, size_t maxsize)
{
	size_t n;
	for(n = 0; n < maxsize && *src; n++, src++);
	return n;
}

char * Strrev(char * src)
{
	int front, back;
	for(front = 0, back = strlen(src)-1; front < back; ++front, --back)
	{
		src[front] ^= src[back];
		src[back] ^= src[front];
		src[front] ^= src[back];
	}
	return src;
}

char * Strrev(char * src, size_t start, size_t end)
{
	if(start < end)
	{
		src[start] ^= src[end];
		src[end] ^= src[start];
		src[start] ^= src[end];

		Strrev(src, start + 1, end - 1);
	}

	return src;
}

char * ReverseWords(char * src)
{
	if(!src) return src;

	char * curr = src;
	char * wordStart = curr, * wordEnd = curr;
	int count = strlen(src) + 1;

	while(count--)
	{
		if(tolower(*curr) >= 'a' && tolower(*curr) <= 'z')
		{
			wordEnd = curr;
		}
		else
		{
			if(wordStart < wordEnd)
			{
				for(; wordStart < wordEnd; ++wordStart, --wordEnd)
				{
					*wordStart ^= *wordEnd;
					*wordEnd ^= *wordStart;
					*wordStart ^= *wordEnd;
				}
			}
			wordStart = curr + 1;
		}

		curr++;
	}

	return src;
}

char * ReverseSentence(char * src)
{
	if(!src) return src;

	return ReverseWords(Strrev(src));
}

bool AreAnagrams(const char * str1, const char * str2)
{
	int histogram[256] = { 0 };

	while(*str1)
	{
		histogram[*str1++]++;
	}

	while(*str2)
	{
		histogram[*str2++]--;
	}

	for(int i = 0; i < 256; i++)
	{
		if(histogram[i] != 0)
		{
			return false;
		}
	}

	return true;
}

const char * Strstr(const char * str1, const char * str2)
{
	if(!str1 || !str2) return 0;

	unsigned int len = strlen(str2);

	while(*(str1 + len - 1))
	{
		if(*str1 == *str2 && *(str1 + len - 1) == *(str2 + len - 1))
		{
			int i = (len > 1) ? 1 : 0;
			for(; i < len - 1 && *(str1 + i) == *(str2 + i); i++);
			if(i == len - 1) return str1;
		}

		str1++;
	}

	return 0;
}

const char * Strchr(const char * str, const char c)
{
	if(!str) return 0;

	while(*str)
	{
		if(*str == c) return str;
		str++;
	}

	return 0;
}

const char FirstNonRepeated(const char * str)
{
	unsigned int histogram[256] = { 0 };

	for(int i = 0; str[i]; ++i) histogram[tolower(str[i])]++;

	for(int i = 0; str[i]; ++i)
	{
		if(histogram[tolower(str[i])] == 1)
		{
			return str[i];
		}
	}

	return '\0';
}

void RemoveChars(char * str, const char remove[])
{
	unsigned int histogram[256] = { 0 };

	while(*remove) histogram[*remove++]++;

	const char * temp = str;
	while(*temp)
	{
		if(!histogram[*temp])
		{
			*str = *temp;
			++str;
		}
		++temp;
	}
	*str = '\0';
}

const int StrToInt(const char * str)
{
	int num = 0, sign = 1;

	if(!str) return num;

	if(*str == '-')
	{
		sign = -1;
		str++;
	}

	while(*str)
	{
		num *= 10;
		num += *str++ - '0';
	}

	return sign * num;
}

void IntToStr(int num, char * str)
{
	unsigned int i = 0, j = 0;

	if(num < 0)
	{
		str[i] = '-';
		num *= -1;
		i++;
		j++;
	}

	while(num)
	{
		str[i++] = "0123456789"[num % 10];
		num /= 10;
	}

	str[i] = '\0';

	while(--i > j)
	{
		str[i] ^= str[j];
		str[j] ^= str[i];
		str[i] ^= str[j];
		j++;
	}
}

char * Strtok(char * str, const char * delimiters)
{
	static char * strStart = NULL;
	static unsigned char bhisto[16];
	char * tokStart, * retStr = NULL;

	if(str != NULL)
	{
		strStart = str;
		for(int i = 0; i < 16; i++) bhisto[i] = 0;
		while(*delimiters)
		{
			bhisto[*delimiters/CHAR_BIT] |= (1 << (*delimiters % CHAR_BIT));
			delimiters++;
		}
	}

	while(*strStart)
	{
		if(bhisto[*strStart/CHAR_BIT] & (1 << (*strStart % CHAR_BIT)))
		{
			strStart++;
		}
		else
		{
			break;
		}
	}

	if(*strStart)
	{
		tokStart = strStart;

		while(*strStart)
		{
			if(bhisto[*strStart/CHAR_BIT] & (1 << (*strStart % CHAR_BIT)))
			{
				break;
			}

			strStart++;
		}

		if(strStart > tokStart)
		{
			retStr = (char *)malloc((strStart - tokStart) + 1);
			if(retStr)
			{
				retStr[strStart - tokStart] = '\0';
				for(int i = 0; i < (strStart - tokStart); i++) retStr[i] = tokStart[i];
			}
		}
	}

	return retStr;
}